home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / pcxpas.com / PCX256.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-10-15  |  4.3 KB  |  146 lines

  1. unit PCX256;
  2.  
  3. (* This is a unit to display 320 x 200 x 256-color .PCX files. The actual
  4.    work of decoding the file and moving the data into memory is done in
  5.    assembler and is quite fast. (You don't need TASM or any knowledge of
  6.    assembly language. As long as PCX256.OBJ is present, it will be linked
  7.    into the unit when you compile.)
  8.  
  9.    It's assumed that the image is the width of the screen and that you will
  10.    set the correct display mode. The unit doesn't check to see what format
  11.    the .PCX file is in, although it will flag an error if the file was
  12.    produced by an early version of Paintbrush that doesn't have palette
  13.    information.
  14.  
  15.    See SHOW256.PAS for a sample implementation.
  16.  
  17.    References:
  18.    ~~~~~~~~~~
  19.    Richard F. Ferraro, "Programmer's Guide to the EGA and VGA Cards"
  20.    (Addison-Wesley, 1988).
  21.  
  22.    "Technical Reference Manual [for Paintbrush]" (Zsoft, 1988). The
  23.    information in this slim booklet is also found in PCX.DOC, a file
  24.    distributed with at least some versions of Microsoft/PC Paintbrush.
  25.  
  26.    Software:
  27.    ~~~~~~~~
  28.    Besides the various incarnations of Paintbrush (ZSoft and Microsoft),
  29.    the excellent Deluxe Paint II Enhanced (Electronic Arts) can also create
  30.    files in .PCX format. Other graphics programs have conversion utilities.
  31.    *)
  32.  
  33. (* --------------------------------------------------------------------- *)
  34.  
  35. INTERFACE
  36.  
  37. uses DOS;
  38.  
  39. type    RGBrec = record
  40.                    redval, greenval, blueval: byte;
  41.                  end;
  42.  
  43. var     pcxfilename: pathstr;
  44.         file_error: boolean;
  45.         RGBpal: array[0..255] of RGBrec;
  46.         page_addr: word;
  47.  
  48. const   page0 = $A000;
  49.  
  50. procedure READ_PCX256(pfilename: pathstr);
  51.  
  52. (* ------------------------------------------------------------------ *)
  53.  
  54. IMPLEMENTATION
  55.  
  56. var     datalength: word;
  57.         scratch: pointer;
  58.         repeatcount: byte;
  59.         video_index: word;
  60.         palette_start, total_read: longint;
  61.         palette_flag: byte;
  62.         version: word;
  63.  
  64. const   buffsize = 65521;              { Largest possible }
  65.  
  66. procedure DECODE_PCX256; external;
  67. {$L pcx256}
  68.  
  69. procedure READ_PCX256(pfilename: pathstr);
  70.  
  71. var     x, gun, pcxcode: byte;
  72.         pcxfile: file;
  73.  
  74. procedure CLEANUP;
  75.  
  76. begin
  77. close(pcxfile);
  78. freemem(scratch,buffsize);
  79. end;
  80.  
  81. begin    { READ_PCX256 }
  82.  
  83. (* To minimize disk access and speed things up, we read the file into a
  84.    scratchpad in dynamic memory. Large files have to be done in two or more
  85.    chunks because of the 64K limit on dynamic memory variables. *)
  86. getmem(scratch, buffsize);                 { Allocate scratchpad }
  87.  
  88. assign(pcxfile, pfilename);
  89. {$I-} reset(pcxfile, 1);  {$I+}
  90. file_error:= (IOresult <> 0);
  91. if file_error then
  92. begin
  93.   cleanup; exit;
  94. end;
  95. blockread(pcxfile, version, 1);             { Read first two bytes }
  96. file_error:= (hi(version) < 5);             { No palette info. }
  97. if file_error then
  98. begin
  99.   cleanup; exit;
  100. end;
  101. palette_start:= filesize(pcxfile) - 769;
  102.  
  103. seek(pcxfile, 128);                        { Scrap file header }
  104. total_read:= 128;
  105.  
  106. repeatcount:= 0;                           { Initialize assembler vars. }
  107. video_index:= 0;
  108.  
  109. repeat
  110.   blockread(pcxfile, scratch^, buffsize, datalength);
  111.   inc(total_read, datalength);
  112.   if (total_read > palette_start) then
  113.       dec(datalength, total_read - palette_start);
  114.   decode_pcx256;                                 { Decode and display }
  115. until (eof(pcxfile)) or (total_read>= palette_start);
  116.  
  117. (* The last 769 btes of the file are palette information, starting with a
  118.    one-byte flag. Each group of three bytes represents the RGB values of
  119.    one of the color registers. The values have to be divided by 4 to be
  120.    brought within the range 0-63 expected by the registers. *)
  121.  
  122. seek(pcxfile, palette_start);
  123. blockread(pcxfile, palette_flag, 1);
  124. file_error:= (palette_flag <> 12);
  125. if file_error then
  126. begin
  127.   cleanup; exit;
  128. end;
  129. blockread(pcxfile, RGBpal, 768);         { Get palette info. }
  130. for x:= 0 to 255 do
  131. with RGBpal[x] do
  132. begin
  133.   redval:= redval div 4;
  134.   greenval:= greenval div 4;
  135.   blueval:= blueval div 4;
  136. end;
  137. cleanup;
  138. end;  { READ_PCX_FILE }
  139.  
  140. (* -------------------------- Initialization ----------------------------- *)
  141.  
  142. BEGIN
  143. page_addr:= page0;                          { Destination for data }
  144. END.
  145.  
  146.